android 自定义预制APP分区

1.先要能被PMS扫描到,在构造函数里添加一条扫描记录,还要设置加载一些库的路径,比如:

 

    public PackageManagerService(Context context, Installer installer,

              boolean factoryTest, boolean onlyCore) {

......

                File oem3rdAppDir = new File(Environment.getOemDirectory(), "preloadapp");
                scanDirLI(oem3rdAppDir, 0, scanFlags, 0);


                // Remove disable package settings for updated system apps that were
                // removed via an OTA. If the update is no longer present, remove the
                // app completely. Otherwise, revoke their system privileges.
                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);

......

}

 

 

    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
......
        boolean isOem3rdApp = codePath.startsWith("/oem/preloadapp") ? true : false;

        if (isApkFile(codeFile) || isOem3rdApp) {。。。。。。}
 

 

 

2.直接扫描进去可能会遇到一下问题,比如APP启动报错,卸载后重启会又加载到APP等。

  2.1 APP启动报错,这可能涉及到证书的问题,预制APP可以不用检查证书,可以在 PackageParser.java 里添加如下:

 

    private static void collectCertificates(Package pkg, File apkFile, int parseFlags)
            throws PackageParserException {

......

 

        StrictJarFile jarFile = null;
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
            // Ignore signature stripping protections when verifying APKs from system partition.
            // For those APKs we only care about extracting signer certificates, and don't care
            // about verifying integrity.
            boolean signatureSchemeRollbackProtectionsEnforced =
                    (parseFlags & PARSE_IS_SYSTEM_DIR) == 0;

            boolean IsPrebuiltApp = apkPath != null
                    && apkPath.startsWith("/oem/preloadapp");
            jarFile = new StrictJarFile(
                    apkPath,
                    !verified, // whether to verify JAR signature
                    IsPrebuiltApp ? false : signatureSchemeRollbackProtectionsEnforced);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 

 

......

  2.2 卸载后重启会又加载到APP,因为系统每次启动都会去扫描,所以出现此问题的解决思路是在卸载之后把改APP记录到某个文件,开机后每次扫描的时候做个判断,如果是被卸载的预制APP,则直接返回,比如:

 

    private boolean deletePackageLIF(String packageName, UserHandle user,
            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
            PackageRemovedInfo outInfo, boolean writeSettings,
            PackageParser.Package replacingPackage) {

......

 

        if (isSystemApp(ps)) {
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
            // When an updated system application is deleted we delete the existing resources
            // as well and fall back to existing code in system partition
            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
        } else {
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);

            if(ps.pkg != null && ps.pkg.baseCodePath != null){
                String path = ps.pkg.baseCodePath.substring(0, ps.pkg.baseCodePath.lastIndexOf("/"));

                这里根据卸载APP的path判断是否是需要预留的APP,如果是则记录到文件

            }

            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
                    outInfo, writeSettings, replacingPackage);
        }

 

 

......

}

 

    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
            throws PackageManagerException {
         这里可以判断是否是已经卸载的预制APP,如果是则直接返回,不用继续加载
         if(。。。。。。)return pkg;

。。。。。。

}

 

 

 

 

 

 

 

 


 

 

 

posted @ 2018-10-24 10:45  Jokeyyu  阅读(987)  评论(0编辑  收藏  举报